#include "VideoPlayer.h"
#include "clocker.h"

#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <signal.h>
#include <stdio.h>

#define log(...) do{                 \
            printf("video player : ");  \
            printf(__VA_ARGS__);     \
            printf("\n");            \
        } while(0);

VideoPlayer::VideoPlayer()
{
    m_rgb = new struct rgb24_object;
    m_frame_index = new std::queue<int>;

    this->m_start_flag = false;
    this->m_pause_flag = false;
    this->m_stop_flag = false;

    this->player = nullptr;
    this->frame = nullptr;

    log("param init success.");

    start_thread_frame();
    start_thread_player();
}

VideoPlayer::~VideoPlayer()
{
    rgb24_deinit(m_rgb);

    delete m_rgb;
    delete m_frame_index;

    if(this->player != nullptr)
    {
        delete this->player;
    }

    if(this->frame != nullptr)
    {
        delete this->frame;
    }
}

int VideoPlayer::start(void)
{
    this->m_start_flag = true;
    return 0;
}
int VideoPlayer::pause(void)
{
    this->m_pause_flag = true;
    return 0;
}

int VideoPlayer::stop(void)
{
    this->m_stop_flag = true;
    return 0;
}

static void thread_frame(struct rgb24_object *p_rgb, std::queue<int> *p_queue, bool *p_start_flag, bool *p_pause_flag, bool *p_stop_flag)
{
    int buf_idx = 0;
    int ret;

    int i, j;
    int x = 0;
    int y = 0;
    uint32_t word;

    log("thread_frame thread start.");

    while (true)
    {
        /* 操作索引 */
        if (buf_idx > 2) buf_idx = 0;

        /* 面板控制 */
        if ((*p_start_flag == true) && (*p_pause_flag == false) && (*p_stop_flag == false))  // 播放
        {
            
            // 查看剩余空间
            if (p_queue->size() >= 2) continue;

            // 获取文件中一帧图片
            ret = rgb24_get_frame(p_rgb);  
            if (ret < 0) {
                log("file null.");
                getchar();
                exit(0);
            }
            log("image:[%d].\n", ret);
            // clocker_start();
            memcpy(drm_buf[buf_idx].vaddr, p_rgb->frame_buffer, 3 * p_rgb->pix_height * p_rgb->pix_width);
            // for(j = 0; j < p_rgb->pix_height; j++){
            //     for(i = 0 ; i < p_rgb->pix_width; i++){
            //         if((j+y) < drm_buf->height && (i+x)<drm_buf->width) {
            //             word = 0;
            //             word =  ((word | p_rgb->frame_buffer[(j*p_rgb->pix_width+i)*3+0])<<16) | 
            //                     ((word | p_rgb->frame_buffer[(j*p_rgb->pix_width+i)*3+1])<<8) | 
            //                     ((word | p_rgb->frame_buffer[(j*p_rgb->pix_width+i)*3+2]));
            //             (drm_buf+buf_idx)->vaddr[(j+y)*drm_buf->width+(x+i)] = word;
            //         }
            //         else
            //             continue;
            //     }
            // }
            // clocker_end();

            // 入栈
            p_queue->push(buf_idx);
            buf_idx++;
            
        }
        else if ((*p_start_flag == false) && (*p_pause_flag == true) && (*p_stop_flag == false))
        {
            // 暂停
        }
        else if ((*p_start_flag == false) && (*p_pause_flag == false) && (*p_stop_flag == true))
        {
            // 停止
        }
        else
        {
            // *p_start_flag = false;
            // *p_pause_flag = false;
            // *p_stop_flag = false;
        }

        //sleep(1);
        // log("p_start_flag:[%d], p_pause_flag:[%d], p_stop_flag:[%d].", *p_start_flag, *p_pause_flag, *p_stop_flag);
    }

    log("thread_frame thread exit.");
}

int VideoPlayer::start_thread_frame(void)
{
    rgb24_init(this->m_rgb);

    frame = new std::thread(thread_frame, this->m_rgb,this->m_frame_index, &this->m_start_flag, &this->m_pause_flag, &this->m_stop_flag);
    frame->detach();
    return 0;
}

static void thread_player(std::queue<int> *p_queue)
{
    int ret;
    log("thread_player thread start.");

    while (true)
    {
        if (!p_queue->empty())
        {   
            clocker_end();
            clocker_start();
            ret = p_queue->front();
            //log("show image : [%d].", ret);
            // clocker_start();
            drm_encap_set_fb_num(ret);
            // clocker_end();
            //log("show ok");
            p_queue->pop();
            
        }
        usleep(30 * 1000);
        //sleep(1);
        //log("p_queue->size:[%d].", p_queue->size())
    }
}

int VideoPlayer::start_thread_player(void)
{
    int ret;

    drm_encap_init();

    player = new std::thread(thread_player, this->m_frame_index);
    player->detach();
    return 0;
}
